class Snowflake {
  constructor(datacenterId = 0, workerId = 0, sequence = 0) {
    // 基础配置（可根据项目需求调整）
    this.twepoch = 1609459200000; // 起始时间戳：2021-01-01 00:00:00
    this.datacenterIdBits = 5;    // 数据中心ID位数（0-31）
    this.workerIdBits = 5;        // 机器ID位数（0-31）
    this.sequenceBits = 12;       // 序列号位数（0-4095）

    // 计算最大取值
    this.maxDatacenterId = -1 ^ (-1 << this.datacenterIdBits);
    this.maxWorkerId = -1 ^ (-1 << this.workerIdBits);
    this.maxSequence = -1 ^ (-1 << this.sequenceBits);

    // 位移配置
    this.workerIdShift = this.sequenceBits;
    this.datacenterIdShift = this.sequenceBits + this.workerIdBits;
    this.timestampLeftShift = this.sequenceBits + this.workerIdBits + this.datacenterIdBits;

    // 校验参数
    if (datacenterId < 0 || datacenterId > this.maxDatacenterId) {
      throw new Error(`数据中心ID需在 0-${this.maxDatacenterId} 之间`);
    }
    if (workerId < 0 || workerId > this.maxWorkerId) {
      throw new Error(`机器ID需在 0-${this.maxWorkerId} 之间`);
    }

    // 初始化状态
    this.datacenterId = datacenterId;
    this.workerId = workerId;
    this.sequence = sequence;
    this.lastTimestamp = -1;
  }

  // 获取当前毫秒时间戳
  #getCurrentTimestamp() {
    return Date.now();
  }

  // 处理时钟回拨
  #waitNextTimestamp(lastTimestamp) {
    let timestamp = this.#getCurrentTimestamp();
    while (timestamp <= lastTimestamp) {
      timestamp = this.#getCurrentTimestamp();
    }
    return timestamp;
  }

  // 生成单个ID
  generate() {
    let timestamp = this.#getCurrentTimestamp();

    // 处理时钟回拨
    if (timestamp < this.lastTimestamp) {
      console.warn(`时钟回拨：当前时间(${timestamp}) < 上次时间(${this.lastTimestamp})，将等待有效时间`);
      timestamp = this.#waitNextTimestamp(this.lastTimestamp);
    }

    // 处理同一时间戳的序列号
    if (timestamp === this.lastTimestamp) {
      this.sequence = (this.sequence + 1) & this.maxSequence;
      if (this.sequence === 0) {
        timestamp = this.#waitNextTimestamp(this.lastTimestamp);
      }
    } else {
      this.sequence = 0;
    }

    this.lastTimestamp = timestamp;

    // 组合ID（使用BigInt避免精度丢失）
    return (
      BigInt(timestamp - this.twepoch) << BigInt(this.timestampLeftShift) |
      BigInt(this.datacenterId) << BigInt(this.datacenterIdShift) |
      BigInt(this.workerId) << BigInt(this.workerIdShift) |
      BigInt(this.sequence)
    );
  }
}

// 初始化默认实例（默认数据中心ID=0，机器ID=0，可根据部署环境修改）
const defaultSnowflake = new Snowflake(0, 0);

/**
 * 生成雪花ID（默认使用全局实例）
 * @returns {string} 雪花ID字符串（避免BigInt在JSON中异常）
 */
function generateSnowflakeId() {
  return defaultSnowflake.generate().toString();
}

/**
 * 创建自定义雪花实例（用于多节点部署，需确保datacenterId+workerId唯一）
 * @param {number} datacenterId 数据中心ID（0-31）
 * @param {number} workerId 机器ID（0-31）
 * @returns {Object} 自定义实例（含generate方法）
 */
function createSnowflakeInstance(datacenterId, workerId) {
  const instance = new Snowflake(datacenterId, workerId);
  return {
    generateId: () => instance.generate().toString()
  };
}

// 导出工具方法
export { generateSnowflakeId, createSnowflakeInstance };